﻿/*    
Nemulation: A .NET based framework/platform for virtualization applications
Copyright (C) 2011 Bryan Perris

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NEmu.Utilities;
using System.Reflection;
using NEmu.Memory.MemoryPages;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace NEmu.TestUnits
{
    [TestFixture, Description("Tests savestating of a machine")]
    public unsafe class SavestateTester
    {
        [Test, Description("Tests savestate of a machine")]
        public void Test_SaveLoadState()
        {
            SimpleVMachine machine = new SimpleVMachine();
            machine.Run();
            SaveStateManager.SaveStatePath = "C:\\tmp\\";
            SaveStateManager.SaveState<SimpleVMachine>(machine, 0);
            machine = null;
            machine = SaveStateManager.LoadState<SimpleVMachine>(0);
            Assert.AreEqual(true, machine.IsBooted);
            Assert.AreEqual(machine.MachineMemory.ParentMachine, machine);
        }

        [Test, Description("Tests serialization of struct pages")]
        public unsafe void Test_StructSave()
        {
            StructMemoryPage<TestStruct> page = new StructMemoryPage<TestStruct>();
            TestStruct* ptr = (TestStruct*)page.StructPtr;
            ptr->a = 0xA0;
            ptr->b = 0xFFFF;
            ptr->c = 0xFABC;
            ptr->d[0x000] = 0xBE;
            ptr->d[0x025] = 0xEF;
            ptr->d[0x100] = 0xCE;
            FileStream file = new FileStream("C:\\tmp\\struct.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(file, page);
            file.Position = 0;
            StructMemoryPage<TestStruct> page2 = (StructMemoryPage<TestStruct>)formatter.Deserialize(file);
            file.Close();
            ptr = (TestStruct*)page.StructPtr;
            Assert.AreEqual(ptr->a, 0xA0);
            Assert.AreEqual(ptr->b, 0xFFFF);
            Assert.AreEqual(ptr->c, 0xFABC);
            Assert.AreEqual(ptr->d[0x000], 0xBE);
            Assert.AreEqual(ptr->d[0x025], 0xEF);
            Assert.AreEqual(ptr->d[0x100], 0xCE);
            page.Dispose();
            page2.Dispose();
            file.Dispose();
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    unsafe struct TestStruct
    {
        public byte a;
        public long b;
        public int c;
        public fixed byte d[0x100];
    }
}
